package org.setaria.control
{
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
	import flash.xml.XMLNode;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.collections.XMLListCollection;
	import mx.controls.Tree;
	import mx.controls.treeClasses.DefaultDataDescriptor;
	import mx.controls.treeClasses.ITreeDataDescriptor;
	import mx.core.IIMESupport;
	import mx.core.mx_internal;
	import mx.events.FlexEvent;
	import mx.events.FlexMouseEvent;
	import mx.events.ListEvent;
	
	import org.setaria.skins.control.ComboBoxTreeSkin;
	
	import spark.components.Button;
	import spark.components.PopUpAnchor;
	import spark.components.TextInput;
	import spark.components.supportClasses.SkinnableContainerBase;
	import spark.events.IndexChangeEvent;
	import spark.events.TextOperationEvent;
	
	[Event(name="change",type="spark.events.IndexChangeEvent")]
	
	use namespace mx_internal;
	public class ComboBoxTree extends SkinnableContainerBase implements IIMESupport
	{
		///标志是否可编辑
		private var _editable:Boolean = true;
		///树的数据源
		private var _dataProvider:ICollectionView = null;
		///选中的对象
		private var _selectedItem:Object = null;
		
		private var _imeMode:String;
		/**
		 * 显示的字段
		 * */
		public var labelField:String = "label";
		
		/**
		 * 区别item的唯一标识属性名
		 * */
		public var identityField:String = "id";
		
		
		public function set editable(data:Boolean):void{
			this._editable = data;
			invalidateDisplayList();
		}
		public function get editable():Boolean{
			return _editable;
		}
		public function set selectedItem(data:Object):void{
			this._selectedItem = findItemByIdentityField(_dataProvider,data[identityField]);
			dispatchEvent(new IndexChangeEvent(IndexChangeEvent.CHANGE));
			invalidateDisplayList();
		}
		public function get selectedItem():Object{
			return _selectedItem;
		}
		public function get imeMode():String
		{
			return _imeMode;
		}
		
		public function set imeMode(value:String):void
		{
			if (textInput)
			{
				textInput.textDisplay.imeMode = value;
//				textInput.textDisplayProperties = BitFlagUtil.update(
//					uint(textDisplayProperties), IME_MODE_PROPERTY_FLAG, true);
			}
			else
			{
//				textDisplayProperties.imeMode = value;
			}
			
			// Generate an UPDATE_COMPLETE event.
			invalidateProperties();     
		}
		public function get enableIME():Boolean
		{
			return editable;
		}
		/**
		 * 设置数据源
		 * @param data Object 支持的数据格式 XML,XMLList,Array,IList,其他数据会被封装成一个IList
		 * */
		public function set dataProvider(data:Object):void{
			// handle strings and xml
			if (typeof(data)=="string")
				data = new XML(data);
			else if (data is XMLNode)
				data = new XML(XMLNode(data).toString());
			else if (data is XMLList)
				data = new XMLListCollection(data as XMLList);
			
			if (data is XML)
			{
				var xl:XMLList = new XMLList();
				xl += data;
				_dataProvider = new XMLListCollection(xl);
			}
				//if already a collection dont make new one
			else if (data is ICollectionView)
			{
				_dataProvider = ICollectionView(data);
			}
			else if (data is Array)
			{
				_dataProvider = new ArrayCollection(data as Array);
			}
			else if (data is Object)
			{
				var tmp:Array = [];
				tmp.push(data);
				_dataProvider = new ArrayCollection(tmp);
			}
			else
			{
				_dataProvider = new ArrayCollection();
			}
			invalidateProperties();
		}
		public function get dataProvider():Object{
			return _dataProvider;
		}
		
		/**
		 *  @private
		 */
		mx_internal var _dataDescriptor:ITreeDataDescriptor = new DefaultDataDescriptor();
		
		public function ComboBoxTree()
		{
			super();
			this.setStyle("skinClass",ComboBoxTreeSkin)
		}
		[SkinPart(required="false")]
		/**
		 * 控制下来树的显示和关闭
		 * */
		public var openButton:Button;
		[SkinPart(required="false")]
		/**
		 * 提示信息的输入框
		 * */
		public var textInput:TextInput;
		[SkinPart(required="false")]
		/**
		 * 树的容器
		 * */
		public var popUp:PopUpAnchor;
		[SkinPart(required="false")]
		/**
		 * 树
		 * */
		public var tree:Tree;
		
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth,unscaledHeight);
			if(this.selectedItem){
				this.textInput.selectAll();
				this.textInput.insertText(this.selectedItem[labelField]); 
			}else{
				this.textInput.text= "";
			}
			textInput.editable = editable;
		}
		
		override protected function partAdded(partName:String, instance:Object):void{
			super.partAdded(partName,instance);
			if(instance == openButton){
				openButton.addEventListener(MouseEvent.CLICK,openButtonHandler);
				openButton.focusEnabled = false;
			}else if(instance == textInput){
				textInput.addEventListener(TextOperationEvent.CHANGE,textInput_changeHandler);
				textInput.addEventListener(FocusEvent.FOCUS_IN, textInput_focusInHandler, true);
				textInput.addEventListener(FocusEvent.FOCUS_OUT, textInput_focusOutHandler, true);
				textInput.addEventListener(FlexEvent.ENTER,textInput_EnterHandler);
//				textInput.focusEnabled = false;//取消焦点则不能输入中文
			}else if(instance == popUp){
				popUp.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE,popUp_MouseDownOutSide_Handler);
			}else if(instance == tree){
				tree.doubleClickEnabled = true;
				tree.addEventListener(MouseEvent.DOUBLE_CLICK,selectedItemHandler);
				tree.dataProvider = dataProvider;
				tree.labelField = labelField;
			}
		}
		
		override protected function partRemoved(partName:String, instance:Object):void{
			if(instance == openButton){
				openButton.removeEventListener(MouseEvent.CLICK,openButtonHandler);
			}else if(instance == textInput){
				textInput.removeEventListener(TextOperationEvent.CHANGE,textInput_changeHandler);
				textInput.removeEventListener(FocusEvent.FOCUS_IN, textInput_focusInHandler, true);
				textInput.removeEventListener(FocusEvent.FOCUS_OUT, textInput_focusOutHandler, true);
				textInput.removeEventListener(FlexEvent.ENTER,textInput_EnterHandler);
				//				textInput.focusEnabled = false;//取消焦点则不能输入中文
			}else if(instance == popUp){
				popUp.removeEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE,popUp_MouseDownOutSide_Handler);
			}else if(instance == tree){
				tree.removeEventListener(MouseEvent.DOUBLE_CLICK,selectedItemHandler);
			}
			super.partRemoved(partName,instance);
		}
		
		private function setSelectedItem(obj:Object):void{
			this._selectedItem = obj;
			dispatchEvent(new IndexChangeEvent(IndexChangeEvent.CHANGE));
			invalidateDisplayList();
		}
		
		/**
		 * 控制下拉列表的显示与隐藏
		 * */
		protected function openButtonHandler(e:MouseEvent = null):void{
			if(this.skin.currentState == "normal"){
				this.skin.currentState = "open";
				textInput_changeHandler();
			}else{
				this.skin.currentState = "normal";
			}
		}
		/**
		 * 设置选中的Item
		 * */
		protected function selectedItemHandler(e:MouseEvent = null):void{
			if(tree.selectedItem){
				setSelectedItem(tree.selectedItem);
				openButtonHandler();
			}
		}
		/**
		 * 根据输入的信息选中第一个以输入文本开头的对象
		 * */
		protected function textInput_changeHandler(e:TextOperationEvent = null):void{
			if(this.skin.currentState != "open"){
				this.skin.currentState = "open";
			}
			var text:String = textInput.text;
			if(text == null || text == ""){
				setSelectedItem(null);
			}else{
				tree.selectedItem = findItemByLabelField(_dataProvider,text);
				tree.scrollToIndex(tree.selectedIndex<0 ? 0 : tree.selectedIndex);
			}
			
		}
		protected function textInput_focusInHandler(event:FocusEvent):void
		{
				this.skin.currentState = "open";
				if(editable){
					textInput_changeHandler();
				}
		}
		protected function textInput_focusOutHandler(event:FocusEvent):void
		{
			this.skin.currentState = "normal";
		}
		protected function textInput_EnterHandler(event:FlexEvent):void{
			selectedItemHandler();
		}
		protected function popUp_MouseDownOutSide_Handler(event:FlexMouseEvent):void{
			this.skin.currentState = "normal";
		}
		
		mx_internal function getChildren(item:Object, view:Object):ICollectionView
		{
			//get the collection of children
			var children:ICollectionView = _dataDescriptor.getChildren(item, view);
			return children;
		}
		/**
		 * 查找符合输入条件的第一个对象 
		 * */
		protected function findItemByLabelField(data:ICollectionView,value:String):Object{
			if (data)
			{
				var cursor:IViewCursor = data.createCursor();
				while (!cursor.afterLast)
				{
					var current:Object = cursor.current;
					if(current){
						if(String(current[labelField]).indexOf(value)==0){
							return current;
						}else{
							if(_dataDescriptor.isBranch(current, cursor.view) && _dataDescriptor.hasChildren(current, cursor.view)){
								tree.expandItem(current, true);
								var obj:Object = findItemByLabelField(getChildren(current, cursor.view),value);
								if(obj){
									return obj;
								}
								tree.expandItem(current, false);
							}
						}
					}
					cursor.moveNext();
				}
			}
			return null;
		}
		/**
		 * 查找和设置对象 identity字段值相等的对象 
		 * */
		protected function findItemByIdentityField(data:ICollectionView,value:String):Object{
			if (data)
			{
				var cursor:IViewCursor = data.createCursor();
				while (!cursor.afterLast)
				{
					var current:Object = cursor.current;
					if(current){
						if(String(current[identityField]) == value){
							return current;
						}else{
							if(_dataDescriptor.isBranch(current, cursor.view) && _dataDescriptor.hasChildren(current, cursor.view)){
								var obj:Object = findItemByLabelField(getChildren(current, cursor.view),value);
								if(obj){
									return obj;
								}
							}
						}
					}
					cursor.moveNext();
				}
			}
			return null;
		}
		
	}
}